import java.util.ArrayList;
import java.util.HashMap;
import java.sql.*;

/*
 * Similar to ACO but disregards distance. The pheromone updating is also modified. 
 */
public class AntSystem {
	
		//alpha is a factor of the number of users assume users ~ 1000
		private static final double ALPHA = 1.0 / 1000.0 ;
		private static final double BETA = 1.01;
	
		private int userListenCount;
		private double userTotalListens;
		private ArrayList<Double> userPrefs;
		private ArrayList<Double> pheros; 
		
		/*
		 * Constructor for existing system.
		 */
		public AntSystem( int userListenCount, double totalListens,  double[] userPrefs, ArrayList<Double> pheros) {

			this.pheros = new ArrayList<Double>(); 
			
			for (int i=0; i<pheros.size(); i++) {
				this.pheros.add(pheros.get(i));
			}
			
			this.userPrefs = new ArrayList<Double>(); 
			for (int i=0; i< 10; i++) {
				this.userPrefs.add(userPrefs[i]);
			}
			this.userListenCount = userListenCount;
			
			userTotalListens = totalListens;
		}
		
		/*
		 * When new pheromones are added, normalize the pheromone paths into the range (0,1)
		 */
		private void normalizePheros() {
			// find max of pheromones
			double max = 0.0;
			double curPhero = 0.0;
			for (int i=0; i<pheros.size(); i++) 
				if (curPhero > max) max = curPhero;
			for (int j=0; j<pheros.size(); j++) pheros.set(j, pheros.get(j)/(max+.000001));
			
		}
		
		/*
		 * Updates the pheromone paths.
		 */
		public ArrayList<Double> updatePheros() {
			increasePheros();
			//normalizePheros();
			return this.pheros;
		} 
		
		private void increasePheros() {
			for (int i=0; i<pheros.size(); i++) {
				double newPhero = ALPHA * userPrefs.get(i) 
									* Math.exp( -1.0 / userListenCount)
									* Math.pow(BETA, userTotalListens);
				pheros.set(i, newPhero);
			}
		} 
}
